Subject : Try to do a Java consumer
Hello,
I dont know about Lotusscript's WSs, but you can do this with a java webservice.
You can use the following class as a Callback handler:
package com.security.handlers;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.xml.soap.SOAPException;
import lotus.domino.axis.AxisFault;
import lotus.domino.axis.Message;
import lotus.domino.axis.MessageContext;
import lotus.domino.axis.encoding.Base64;
import lotus.domino.axis.handlers.BasicHandler;
//import lotus.domino.types.MessageElement;
import lotus.domino.axis.message.MessageElement;
import lotus.domino.axis.message.PrefixedQName;
import lotus.domino.axis.message.SOAPEnvelope;
import lotus.domino.axis.message.SOAPHeaderElement;
import lotus.domino.axis.utils.Messages;
import lotus.domino.types.Fault;
public class WsseClientHandler extends BasicHandler {
private static final long serialVersionUID = 1303905861651017621L;
private static final String WSSE_URI = "http://schemas.xmlsoap.org/ws/2002/07/secext ";
private static final String WSU_URI = "http://schemas.xmlsoap.org/ws/2002/07/utility ";
public static final String PASSWORD_WITHOUT = "without password";
public static final String PASSWORD_CLEARTEXT = "cleartext password";
public static final String PASSWORD_DIGEST = "simple password digest";
public static final String PASSWORD_DIGEST_WITH_NONCE = "password+nonce+timestamp digest";
public static final String PASSWORD_OPTION = "wsse password option";
/*
* @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
*/
public void invoke(MessageContext msgContext) throws AxisFault {
log.debug("Enter: WsseClientHandler::invoke");
System.out.println("WsseClientHandler invocado");
try {
Message msg = msgContext.getRequestMessage();//msgContext.getCurrentMessage();
SOAPEnvelope se = msg.getSOAPEnvelope();
SOAPHeaderElement wsseSecurity = new SOAPHeaderElement(new PrefixedQName(WSSE_URI, "Security", "wsse"));
//wsseSecurity.setMustUnderstand(true);
/* wsseSecurity.addChild(createUsernameToken(
msgContext.getUsername(), msgContext.getPassword(),
(String)msgContext.getProperty(PASSWORD_OPTION)));*/
wsseSecurity.addChild(createUsernameToken(
"username", "password",
PASSWORD_DIGEST_WITH_NONCE));
se.addHeader(wsseSecurity);
}
catch( Exception e ) {
log.error( Messages.getMessage("exception00"), e );
throw Fault.makFault(e);
}
log.debug("Exit: WsseClientHandler::invoke");
}
public void onFault(MessageContext msgContext) {
log.debug("Enter: WsseClientHandler::onFault");
log.debug("Exit: WsseClientHandler::onFault");
}
private MessageElement createUsernameToken(String usernameS, String passwordS,
String passwordOption) throws SOAPException {
log.debug("Enter: WsseClientHandler::createUsernameToken");
MessageElement usernameToken = new MessageElement("","wsse:UsernameToken");
/*
if (usernameS == null || passwordS == null || passwordOption == null) {
}
else
*/
if (passwordOption.equals(PASSWORD_WITHOUT)) {
MessageElement username = new MessageElement("", "wsse:Username");
username.setObjectValue(usernameS);
usernameToken.addChild(username);
}
else if (passwordOption.equals(PASSWORD_CLEARTEXT)) {
MessageElement username = new MessageElement("", "wsse:Username");
username.setObjectValue(usernameS);
usernameToken.addChild(username);
MessageElement password = new MessageElement("", "wsse:Password");
password.setObjectValue(passwordS);
usernameToken.addChild(password);
}
else if (passwordOption.equals(PASSWORD_DIGEST)) {
MessageElement username = new MessageElement("", "wsse:Username");
username.setObjectValue(usernameS);
usernameToken.addChild(username);
MessageElement password = new MessageElement("", "wsse:Password");
password.addAttribute("", "Type", "wsse:PasswordDigest");
password.setObjectValue(getBase64Digest(utf8decode(passwordS)));
usernameToken.addChild(password);
}
else if (passwordOption.equals(PASSWORD_DIGEST_WITH_NONCE)) {
String nonceS = generateNonce();
byte[] nonceB = Base64.decode(nonceS);
String createdS = generateTimestamp();
byte[] createdB = utf8decode(createdS);
byte[] passwordB = utf8decode(passwordS);
MessageElement username = new MessageElement("", "wsse:Username");
username.setObjectValue(usernameS);
usernameToken.addChild(username);
MessageElement password = new MessageElement("", "wsse:Password");
password.addAttribute("", "Type", "wsse:PasswordDigest");
password.setObjectValue(getBase64Digest(nonceB, createdB, passwordB));
usernameToken.addChild(password);
MessageElement nonce = new MessageElement("", "wsse:Nonce");
nonce.setObjectValue(nonceS);
usernameToken.addChild(nonce);
MessageElement created = new MessageElement(new PrefixedQName(WSU_URI, "Created", "wsu"));
created.setObjectValue(createdS);
usernameToken.addChild(created);
}
else {
log.debug("Exit: WsseClientHandler::createUsernameToken (No UsernameToken created)");
return null;
}
log.debug("Exit: WsseClientHandler::createUsernameToken");
return usernameToken;
}
private String generateNonce() {
// TODO working Nonce generator "private byte[] generateNonce()"
return "LKJlsajfdolUOIJlwkjroasoi0009=--=-=-";
}
private String generateTimestamp() {
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
return dateFormatter.format(new Date());
}
private static byte[] utf8decode(String input) {
// UTF-8 enc
byte[] ret = null;
try {
ret = input.getBytes("UTF-8");
} catch (java.io.UnsupportedEncodingException e) {
e.printStackTrace();
}
return ret;
}
private static synchronized String getBase64Digest(byte[] nonce, byte[] created, byte[] password) {
try {
MessageDigest messageDigester = MessageDigest.getInstance("SHA-1");
// SHA-1 ( nonce + created + password )
messageDigester.reset();
messageDigester.update(nonce);
messageDigester.update(created);
messageDigester.update(password);
return Base64.encode(messageDigester.digest());
} catch (java.security.NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
private static synchronized String getBase64Digest(byte[] password) {
try {
MessageDigest messageDigester = MessageDigest.getInstance("SHA-1");
// SHA-1 ( nonce + created + password )
messageDigester.reset();
messageDigester.update(password);
return Base64.encode(messageDigester.digest());
} catch (java.security.NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
}
And then, you change the deployment descriptor (.wdd) including the call of the handler:
<globalConfiguration>
<requestFlow>
<handler type="java:sisac.security.handlers.WsseClientHandler">
<parameter name="username" value="$%$#$%#$%" />
<parameter name="password" value="!@#!@#!@#" />
<parameter name="wsse password option" value="password+nonce+timestamp digest" />
<!-- <parameter name="action" value="UsernameToken" />
<parameter name="user" value="wss4j" />
<parameter name="passwordCallbackClass" value="samples.stock.client.PWCallback" />
<parameter name="passwordType" value="PasswordDigest" /> -->
</handler>
</requestFlow>
</globalConfiguration>
The .wdd file is a hidden file generated by Domino Designer when you create a Webservice consumer. Once you create the Webservice, you can extract this file through NotesPeek.
Hope this helps.
Feedback response number WEBB8D4GZ6 created by ~Vijay Xantoomargon on 01/14/2011
Consuming a Web Service Requiring W... (~Howard Lopfana... 13.Jan.11)
. . Try to do a Java consumer (~Vijay Xantooma... 14.Jan.11)
. . . . Thanks. I'll give it a try (~Howard Lopfana... 14.Jan.11)